package cn.tedu.charging.order.amqp;

import cn.tedu.charging.common.pojo.consts.AmqpComponentConst;
import cn.tedu.charging.common.pojo.message.DelayCheckMessage;
import cn.tedu.charging.order.service.ConsumerService;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 消费类,负责代表订单接收监听一些队列的消息
 */
@Component
@Slf4j
public class AmpqConsumer {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ConsumerService consumerService;
    /*@RabbitListener(queues = "demo_queue")
    public void consume01(String message){
        log.info("接收到消息:{}",message);
    }*/
    @RabbitListener(queues = AmqpComponentConst.DELAY_BILL_DL_QUEUE)
    public void consumeDelayMessage(String message){
        DelayCheckMessage msg = JSON.parseObject(message, DelayCheckMessage.class);
        //1.做一些抢锁的准备,setnx的操作对象,锁的key值要绑定订单编号
        ValueOperations valueOps = redisTemplate.opsForValue();
        String lockKey="charging:order:"+msg.getBillId()+".lock";//锁的key值
        //2.为循环准备一些参数
        boolean haveLock=false;//抢锁结果
        int count=0;//重抢的次数
        //每次必抢,抢完了再判断结果
        try {
            do {
                //判断一下抢的次数 第一次count=0 重抢三次count>0 count<4 睡200毫秒 重抢三次以上 count>=4
                if (count > 0 && count < 4) {
                    //说明是重抢,需要等待200毫秒
                    Thread.sleep(200);
                } else if (count >= 4) {
                    return;//方法执行结束 不抢锁,也不执行业务了;
                }
                //3.开始抢锁 setnx key value EX 5
                haveLock = valueOps.setIfAbsent(lockKey, "", 5, TimeUnit.SECONDS);
                count++;
            } while (!haveLock);
            //4.抢到锁执行业务
            consumerService.handleCheckNoRes(msg);
        }catch (Exception e){
            log.error("处理延迟消息异常:{}",e);
        }finally {
            //5.释放锁
            if (haveLock) {
                redisTemplate.delete(lockKey);
            }
        }
    }
}
